#include "Level.h"
#include "Character.h"
#include "Camera.h"

Level::Level(string levelName) {
    path = LEVELS_DIR + levelName + "/" ;
    string filename("level.xml");
    
    // Retrieve the level xml
    xmlDoc = new TiXmlDocument((path + filename).c_str());
    if (!xmlDoc->LoadFile()) throw FILE_NOT_FOUND;
    xml = xmlDoc->RootElement();
    
    name  = levelName;
    title = xml->Attribute("name");

    background = new Sprite();
    background->SetImage(imageManager.getImage(xml->Attribute("background"), path));

    foreground = new Sprite();
    foreground->SetImage(imageManager.getImage(xml->Attribute("foreground"), path));
    
    initCharacters();
    initCollidables();
    
    width  = background->GetSize().x;
    height = background->GetSize().y;
    camera = new Camera(this);    
}

void Level::initCharacters() {
    TiXmlElement* charactersXml = xml->FirstChildElement("characters");
    TiXmlElement* characterXml  = charactersXml->FirstChildElement();
    
    do {
        string   name = characterXml->Attribute("name");
        Vector2f position;
        
        position.x = Chameleon(characterXml->Attribute("x"));
        position.y = Chameleon(characterXml->Attribute("y"));
        
        try {
            Character* character = new Character(name,position, this);
            
            character->setX(character->getDefaultPosition().x);
            character->setY(character->getDefaultPosition().y);
            
            characters.push_back(character);
        } catch (Exception e) { throw e; }
        
        // Iterate
        if (charactersXml->IterateChildren(characterXml)) {
            characterXml = charactersXml->IterateChildren(characterXml)->ToElement();
        } else {
            break;
        }
    } while (true);
    
    // The hero is the first character defined
    hero = (Hero*)characters.at(0);
}

void Level::initCollidables() {
    TiXmlElement* objectsXml = xml->FirstChildElement("objects");
    TiXmlElement* objectXml  = objectsXml->FirstChildElement();
    
    do {
        string   filename = objectXml->Attribute("image");
        
        Vector2f position;
        position.x = Chameleon(objectXml->Attribute("x"));
        position.y = Chameleon(objectXml->Attribute("y"));
        
        int width  = Chameleon(objectXml->Attribute("width"));
        int height = Chameleon(objectXml->Attribute("height"));

        Sprite* object;
        if (((string)objectXml->Attribute("texture")).compare("yes") == 0) {
            object = new Textured(imageManager.getImage(filename, path), width, height);
        } else {
            object = new Sprite(imageManager.getImage(filename, path));
        }
        
        object->SetX(position.x);
        object->SetY(position.y);
        
        collidables.push_back(object);
        
        // Iterate
        if (objectsXml->IterateChildren(objectXml)) {
            objectXml = objectsXml->IterateChildren(objectXml)->ToElement();
        } else {
            break;
        }
    } while (true);
}

string Level::getName()   { return name; }
string Level::getTitle()  { return title;}
int    Level::getWidth()  { return width; }
int    Level::getHeight() { return height; }

Level::~Level() {
    delete background;
    delete foreground;
    delete hero;
    delete camera;
    delete xmlDoc;
}